import util
import logging

class StatisticsCollector:
  def __init__(self, sequences, annotations):
  
    #random initialization
    if sequences == None and annotations == None:
      stateset = ["B", "I", "S"]
      stateGiven = dict()
      tokenGiven = dict()
      import random
      for s in stateset:
        
        stateGiven[s] = util.Counter()
        #if s == "S":
        #  continue
        tokenGiven[s] = util.Counter()
      for s in stateset:
        for c in ['A', 'C', 'T', 'G']:
          if s == "S":
            continue
          else:
            tokenGiven[s][c] = random.random()
        for t in stateset:
          if t == "S":
            continue
          else:
            stateGiven[s][t] = random.random()
      for s in stateset:
        stateGiven[s].normalize()
        tokenGiven[s].normalize()
      self.stateset = stateset
      self.stateGiven = stateGiven
      self.tokenGiven = tokenGiven
      return
    
    #regular initialization
    stateset = ["B", "I", "S"]
    logger = logging.getLogger("SupervisedStatisticsCollector")
    state = util.Counter()
    stateGiven = dict()
    tokenGiven = dict()
    for s in stateset:
      stateGiven[s] = util.Counter()
      tokenGiven[s] = util.Counter()
      
    slow = None
    #slow = "true"
    if slow:
      for filename in annotations.keys():
        ann = annotations[filename]
        seq = sequences[filename][0]
        anns = 'B'*len(seq)
        for data in ann:
          anns = anns[:data['start']] + 'I'*data['length'] + anns[data['end'] + 1:]
        logger.debug(len(anns))
        logger.debug(len(seq))
        prevs = start
        for a, s in zip(anns, seq):
          state[a] = state[a] + 1
          if a == 'I':
            tokenGiven["I"][s] = tokenGivenI[s] + 1
          else:
            tokenGiven["B"][s] = tokenGivenB[s] + 1
          #self.logger.debug(prevs)
          stateGiven[prevs][a] = stateGiven[prevs][a] + 1
          prevs = a 
        logger.debug(str(len(seq)) + ", " + str(state["I"]) + ", " + str(state["B"]))    
    else:
      token = util.Counter()
      totallength = 0
      for filename in annotations.keys():
        ann = annotations[filename]
        seq = sequences[filename][0]
        totallength += len(seq)


        stateGiven["S"]["B"] = 1
        inislandsum = 0;
        for data in ann:
          state["I"] = state["I"] + data['length']

          inislandsum += data['length']

          for i in range(data['start'], data['end']):
            tokenGiven["I"][seq[i]] = tokenGiven["I"][seq[i]] + 1
        stateGiven["I"]["I"] = stateGiven["I"]["I"] + inislandsum - len(ann)
        stateGiven["I"]["B"] = stateGiven["I"]["B"] + len(ann)
        stateGiven["B"]["I"] = stateGiven["B"]["I"] + len(ann)
        stateGiven["B"]["B"] = stateGiven["B"]["B"] + len(seq) - (inislandsum - len(ann) ) - len(ann) - len(ann)
        for c in seq:
          token[c] = token[c] + 1

      state["B"] = totallength - state["I"]
      for c in token.keys():
        tokenGiven["B"][c] = token[c] - tokenGiven["I"][c]

    state.normalize()
    stateGiven["I"].normalize()
    stateGiven["B"].normalize()
    tokenGiven["I"].normalize()
    tokenGiven["B"].normalize()
    stateGiven["S"].normalize()
    logger.debug("self.state " + str(state))
    logger.debug("self.stateGivenI " + str(stateGiven["I"]))
    logger.debug("self.stateGivenB " + str(stateGiven["B"]))
    logger.debug("self.stateGivenS " + str(stateGiven["S"])) 
    logger.debug("self.tokenGivenI " + str(tokenGiven["I"]))
    logger.debug("self.tokenGivenB " + str(tokenGiven["B"]))
    
    self.stateset = stateset
    #self.state = state
    self.stateGiven = stateGiven
    self.tokenGiven = tokenGiven
    
  def logAll(self):
    #self.state.logAll()
    for s in self.stateset:
      #print self.stateGiven
      #print self.tokenGiven
      #print s
      self.stateGiven[s].logAll()
      self.tokenGiven[s].logAll()
  def __repr__(self):
    s = ""
    s += "self.stateGivenI " + str(self.stateGiven["I"]) + "\n"
    s += "self.stateGivenB " + str(self.stateGiven["B"]) + "\n"
    s += "self.stateGivenS " + str(self.stateGiven["S"]) + "\n" 
    s += "self.tokenGivenI " + str(self.tokenGiven["I"]) + "\n"
    s += "self.tokenGivenB " + str(self.tokenGiven["B"]) + "\n"
    s += "self.tokenGivenS " + str(self.tokenGiven["S"]) + "\n"
    return s
